<template>
  <div class="data-list">
    <el-table
      v-loading="listLoading"
      :data="records"
      :row-key="idKey"
      :height="height"
      stripe
      border
      highlight-current-row
      style="width: 100%"
    >
      <slot name="row" />
      <template v-if="sortable">
        <el-table-column align="center" label="排序" width="80">
          <template>
            <div class="drag-handler" style="display: inline-block;">
              <svg-icon class="drag-handler-icon" icon-class="drag" />
            </div>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <div
      v-if="pageable"
      v-show="!listLoading"
      style="padding-top:20px; text-align: center;"
    >
      <el-pagination
        :current-page.sync="parameter.page"
        :page-size.sync="parameter.size"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageData.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <el-dialog
      :title="isEdit ? updateTitle : createTitle"
      :visible.sync="dialogVisible"
      :width="editFormWidth"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="showClose"
    >
      <template v-if="dialogVisible">
        <slot name="edit-form" :isEdit="isEdit" :editDataId="editData && editData[idKey]" :editData="editData" />
      </template>
    </el-dialog>
  </div>
</template>

<script>

import Sortable from 'sortablejs'

export default {
  components: {
  },
  props: {
    loadFunc: { type: Function, required: true },
    deleteFunc: { type: Function, default: null },
    parameter: { type: [Object, Number, String, Boolean, Array, Date, Function], default: null },
    autoLoad: { type: Boolean, default: true },
    idKey: { type: String, default: 'id' },
    editFormWidth: { type: String, default: '600px' },
    updateTitle: { type: String, default: '修改' },
    createTitle: { type: String, default: '新增' },
    pageable: { type: Boolean, default: false },
    sortable: { type: Boolean, default: false },
    height: { type: Number, default: null },
    showClose: { type: Boolean, default: false }
  },
  data() {
    return {
      pageData: {
        total: 0,
        records: []
      },
      records: [],
      listLoading: false,
      isEdit: false,
      editData: null,
      dialogVisible: false
    }
  },
  mounted: function() {
    this.autoLoad && this.query()
  },
  methods: {
    query() {
      if (this.pageable) {
        this.parameter.page = 1
      }
      this.loadData()
    },
    loadData() {
      if (this.listLoading) return
      this.listLoading = true

      this.loadFunc(this.parameter).then(resp => {
        this.listLoading = false
        if (resp.code === 0) {
          if (this.pageable) {
            // resp.data = {
            //   total: resp.data.totalElements,
            //   records: resp.data.content
            // }
            this.pageData = resp.data
            this.records = resp.data.records
          } else {
            this.records = resp.data
          }

          if (this.sortable) {
            this.$nextTick(() => {
              this.setSort()
            })
          }
        } else {
          this.$message({ message: resp.message, type: 'warning' })
        }
      }).catch(() => {
        this.listLoading = false
      })
    },
    handleSizeChange(size) {
      this.parameter.size = size
      this.parameter.page = 1

      this.loadData()
    },
    handleCurrentChange(page) {
      this.parameter.page = page

      this.loadData()
    },
    toCreate() {
      this.isEdit = false
      this.editData = null
      this.dialogVisible = true
    },
    toEdit(item) {
      this.isEdit = true
      this.editData = item
      this.dialogVisible = true
    },
    toDelete(item, confirmMsg, deleteSuccessMsg) {
      confirmMsg = confirmMsg || `确认删除当前记录?`
      this.$confirm(confirmMsg, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.delete(item, deleteSuccessMsg)
      })
    },
    delete(item, deleteSuccessMsg) {
      deleteSuccessMsg = deleteSuccessMsg || '删除成功'
      this.deleteFunc(item[this.idKey]).then((resp) => {
        if (resp.code === 0) {
          this.$message({ message: deleteSuccessMsg, type: 'success' })
          this.loadData()
        } else {
          this.$message({ message: resp.message, type: 'warning' })
        }
      })
    },
    afterSave() {
      this.dialogVisible = false
      this.loadData()
    },
    afterCancel() {
      this.dialogVisible = false
    },
    setSort() {
      const el = this.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
      Sortable.create(el, {
        ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
        handle: '.drag-handler',
        animation: 200,
        setData: function(dataTransfer) {
          dataTransfer.setData('Text', '')
          // to avoid Firefox bug
          // Detail see : https://github.com/RubaXa/Sortable/issues/1012
        },
        onEnd: evt => {
          console.log('oldIndex:', evt.oldIndex, 'newIndex:', evt.newIndex)
          const targetRow = this.records.splice(evt.oldIndex, 1)[0]
          this.records.splice(evt.newIndex, 0, targetRow)
          this.$nextTick(() => {
            this.$emit('afterSort', this.records)
          })
        }
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .data-list {
    ::v-deep .sortable-ghost{
      opacity: .8;
      color: #fff!important;
      background: #42b983!important;
    }
    .drag-handler-icon{
      width: 20px;
      height: 20px;
      cursor: pointer;
    }
    ::v-deep .el-button+.el-button {
      margin-left: 0px;
    }
  }

</style>
